Skip to content

feat(agent): add privilege escalation for least-privilege mode#344

Merged
retr0h merged 21 commits intomainfrom
feat/agent-privilege-escalation
Apr 2, 2026
Merged

feat(agent): add privilege escalation for least-privilege mode#344
retr0h merged 21 commits intomainfrom
feat/agent-privilege-escalation

Conversation

@retr0h
Copy link
Copy Markdown
Collaborator

@retr0h retr0h commented Apr 2, 2026

Summary

  • Add RunPrivilegedCmd to the exec Manager interface — prepends sudo to write commands when privilege_escalation.enabled is true
  • Migrate 37 provider call sites across 11 domains from RunCmd to RunPrivilegedCmd for write operations (service, sysctl, hostname, timezone, NTP, user, group, ssh-key, package, power, certificate, DNS)
  • Add preflight verification at agent startup: checks sudo access for 16 commands and verifies 4 Linux capabilities (CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_KILL)
  • Single config toggle: agent.privilege_escalation.enabled
  • All mock expectations enforce read/write distinction — using the wrong method fails the test
  • Feature page with sudoers drop-in, capability setup, systemd unit file, and command reference

Config

agent:
  privilege_escalation:
    enabled: false  # default: backward compatible

When enabled: write commands use sudo, capabilities verified at startup. When disabled: everything runs as current user (no behavior change).

Test plan

  • All 20 provider packages pass
  • Exec manager tests (sudo=true and sudo=false paths)
  • Preflight tests (sudo verification, capability parsing, combined)
  • Build clean, lint clean
  • Zero stray RunCmd for write operations
  • All read operations stay on RunCmd

🤖 Generated with Claude Code

retr0h and others added 15 commits April 2, 2026 13:43
Reference documentation for running the agent as an unprivileged
user. Includes sudoers drop-in, capability setup, systemd unit file,
and full command privilege reference table. Code changes for
privilege escalation support are tracked separately.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add exec manager RunPrivilegedCmd design, config schema for
privilege_escalation (sudo, capabilities, preflight), preflight
check design with example output, and updated command reference
showing which calls use RunCmd vs RunPrivilegedCmd.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Content will live in docs/plans/ as a design spec instead of
user-facing documentation.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Config-driven sudo escalation, RunPrivilegedCmd exec manager method,
Linux capabilities, preflight verification at agent startup, sudoers
drop-in, and full command read/write classification.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
15 tasks covering exec manager RunPrivilegedCmd, preflight checks,
provider migration across 10 domains, and documentation.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add PrivilegeEscalation struct to config types with sudo,
capabilities, and preflight fields. Wire into AgentConfig and
add commented-out defaults to all config files.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add a preflight system that runs during agent start to verify sudo
access and Linux capabilities before accepting jobs. Checks are
controlled by the privilege_escalation config (sudo, capabilities,
preflight flags). Also adds execManager field to Agent struct for
preflight sudo verification.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Migrate all systemctl write commands (start, stop, restart, enable,
disable, daemon-reload) to RunPrivilegedCmd so they run with privilege
escalation. Read-only checks (is-active, is-enabled) remain on RunCmd.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
… ntp writes

Migrate write operations in four providers to use RunPrivilegedCmd
so they are executed with privilege escalation when configured:
- sysctl: sysctl -p <path> and sysctl --system
- host: hostnamectl set-hostname
- timezone: timedatectl set-timezone
- ntp: chronyc reload sources

Read-only operations (sysctl -n, hostnamectl hostname, timedatectl
show, chronyc tracking/sources) remain as RunCmd.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
…ficate, dns writes

Migrate write operations from RunCmd to RunPrivilegedCmd across five
provider domains so privileged commands use sudo/capabilities when
configured. Read-only commands (id, passwd -S, dpkg-query, apt list,
resolvectl status) remain as RunCmd.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add agent-hardening.md feature page documenting least-privilege mode,
sudoers drop-in, Linux capabilities, systemd unit, and preflight checks.
Update configuration.md with privilege_escalation YAML block, env vars,
and section reference table. Add Agent Hardening to the navbar dropdown.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Uncomment privilege_escalation in all config files with preflight
enabled by default. Add to integration test config with preflight
disabled (tests run without sudo/caps).

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
When sudo or capabilities is enabled, the agent now automatically
runs preflight verification at startup. The separate preflight
config field is no longer needed.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace sudo + capabilities booleans with a single enabled toggle.
When enabled, both sudo and capability verification are active.
Update all configs, preflight, docs, and spec.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff            @@
##             main     #344    +/-   ##
========================================
  Coverage   99.91%   99.91%            
========================================
  Files         438      440     +2     
  Lines       21268    21377   +109     
========================================
+ Hits        21249    21358   +109     
  Misses         11       11            
  Partials        8        8            
Files with missing lines Coverage Δ
internal/agent/agent.go 100.00% <100.00%> (ø)
internal/agent/preflight.go 100.00% <100.00%> (ø)
internal/agent/server.go 100.00% <100.00%> (ø)
internal/controller/api/node/user/user_update.go 98.13% <ø> (ø)
internal/exec/exec.go 100.00% <100.00%> (ø)
internal/exec/run_privileged_cmd.go 100.00% <100.00%> (ø)
...work/dns/debian_update_resolv_conf_by_interface.go 100.00% <100.00%> (ø)
internal/provider/node/apt/debian.go 100.00% <100.00%> (ø)
internal/provider/node/certificate/debian.go 100.00% <100.00%> (ø)
...ernal/provider/node/host/debian_update_hostname.go 100.00% <100.00%> (ø)
... and 9 more

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d16126d...680706a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

retr0h and others added 5 commits April 2, 2026 15:15
Extract command execution into a CommandExecutor interface so
RunPrivilegedCmd tests can assert exact command/args via gomock
without executing real commands or triggering sudo prompts.

Co-Authored-By: Claude <noreply@anthropic.com>
Extract command execution into a CommandExecutor interface so
RunPrivilegedCmd tests can assert exact command/args via gomock
without executing real commands or prompting for sudo passwords.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add test cases for invalid hex CapEff, missing CapEff line, and
preflight failure/success in agent Start(). Add defense-in-depth
comment to user update validation.Struct call.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Write a line exceeding bufio.MaxScanTokenSize to trigger a scanner
error, covering the remaining branch in readCapEff.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
@retr0h retr0h merged commit 3b2683e into main Apr 2, 2026
11 checks passed
@retr0h retr0h deleted the feat/agent-privilege-escalation branch April 2, 2026 23:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant